#!/bin/bash
export PATH=$PATH:$JAVA_HOME/bin
# 检 查 是 否 提 供 了 参 数
if [ $# -eq 0 ]; then
  echo "Usage: $0    

"
  echo "Commands:"
  echo "  dump      - dump 堆 内 存 到 文 件 "
  echo "  thread    - 打 印 线 程 信 息 到 文 件 "
  echo "  gc        - 查 看 gc 信 息 "
  echo "  gccause   - 查 看 gc 原 因 "
  echo "  heap      - 查 看 堆 内 存 使 用 情 况 "
  echo "  to16      - 转 为 16 进 制 "
  echo "  cpu       - 显 示 最 消 耗 cpu 的 5 个 线 程 "
  echo "  mem       - 打 印 占 用 内 存 最 大 的 10 个 对 象 "
  exit 1
fi

# 获 取 参 数
COMMAND=$1
PID=$2

# 定 义 输 出 目 录
OUTPUT_DIR="./jvm_reports"
mkdir -p $OUTPUT_DIR

# 根 据 命 令 执 行 相 应 操 作
case $COMMAND in
dump)
  # 生 成 堆 内 存  dump
  HEAP_DUMP_FILE="$OUTPUT_DIR/heap_dump_$PID_$(date +%Y%m%d%H%M%S).hprof"
  echo "Generating heap dump for PID $PID..."
  jmap -dump:live,format=b,file=$HEAP_DUMP_FILE $PID
  if [ $? -eq 0 ]; then
    echo "Heap dump generated: $HEAP_DUMP_FILE"
  else
    echo "Failed to generate heap dump."
  fi
  ;;
thread)
  # 导 出 线 程 信 息
  THREAD_DUMP_FILE="$OUTPUT_DIR/thread_dump_$PID_$(date +%Y%m%d%H%M%S).txt"
  echo "Exporting thread information for PID $PID..."
  jstack -l $PID >$THREAD_DUMP_FILE
  if [ $? -eq 0 ]; then
    echo "Thread dump exported: $THREAD_DUMP_FILE"
  else
    echo "Failed to export thread dump."
  fi
  ;;
gc)
  # 显 示  GC 情 况
  echo "Displaying GC statistics for PID $PID..."
  jstat -gc $PID 1000 5 | column -t
  ;;
gccause)
  # 显 示  GC 原 因
  echo "Displaying GC cause for PID $PID..."
  jstat -gccause $PID 1000 5
  ;;
heap)
  # 显 示 堆 内 存 使 用 情 况
  echo "Displaying heap memory usage for PID $PID..."
  jmap -heap $PID
  ;;
to16)
  # 转 为 16进 制
  echo "将 PID转 为 16进 制 "
  printf "0x%x" $PID
  ;;
cpu)
  # 打 印 最 消 耗 cpu的 5个 线 程
  echo "最 消 耗 cpu的 5个 线 程 "
  top -b -n 1 -H -p $PID | awk '$1 ~ /^[0-9]+$/ && $9 > 0 {printf "Thread ID: %d (Hex: 0x%x), CPU: %.1f%%\n", $1, $1, $9}' | sort -k5 -nr | head -n 5 | while
    read
    line
  do
    echo -e "\e[34m$line\e[0m"
    HEX_ID=$(echo "$line" | awk '{print $5}' | awk -F ')' '{print $1}')
    jstack $PID | awk -v hex="$HEX_ID" '/^".*"/ {in_thread=0} $0 ~ "
nid="hex {in_thread=1} in_thread' | grep -v "^$"
    echo "-----------------------------"
  done
  ;;
mem)
  # 打 印 占 用 内 存 最 大 的 10个 对 象
  echo "占 用 JVM内 存 最 大 的 10个 对 象 "
  jmap -histo:live $PID | awk 'NR == 1 {next} {size_mb = $3 / (1024 * 1024); printf "%-8s %-12s %-12s %-30s %.2f\n", $1, $2, $3, $4, size_mb}' | sort -k5 -nr | hea
  d -n 10 | awk 'BEGIN {print "Num      Instances   Bytes        Class Name                     Size(MB)"} {print $0}'
  ;;
*)
  echo "Unknown command: $COMMAND"
  echo "Usage: $0  

"
  echo "Commands:"
  echo "  dump      - dump堆 内 存 到 文 件 "
  echo "  thread    - 打 印 线 程 信 息 到 文 件 "
  echo "  gc        - 查 看 gc信 息 "
  echo "  gccause    - 查 看 gc原 因 "
  echo "  heap   - 查 看 堆 内 存 使 用 情 况 "
  echo "  to16   - 转 为 16进 制 "
  echo "  cpu  - 显 示 最 消 耗 cpu的 5个 线 程 "
  echo "  mem  - 打 印 占 用 内 存 最 大 的 10个 对 象 "
  exit 1
  ;;
esac
